package com.pro.mianshiti;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author Sanmier
 * @version 1.0
 * @date 2024/4/23
 */
public class Service2 {
    public Map<Long, String> get(List<Long> userIds) {
        Map<Long, String> resultMap = new ConcurrentHashMap<>(); // 使用线程安全的 ConcurrentHashMap

        // 每次最多处理50个用户ID
        int batchSize = 50;

        // 计算需要分成几批请求
        int batches = (int) Math.ceil((double) userIds.size() / batchSize);

        // 每批请求耗时100ms
        int requestTimePerBatch = 100;

        // 用于存储所有批次的 CompletableFuture
        List<CompletableFuture<Void>> futures = new ArrayList<>();

        // 创建线程池，根据需要处理多个批次的请求
        //ThreadPoolExecutor executor = new ThreadPoolExecutor(batches, 0, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(20));
        ExecutorService executor = Executors.newFixedThreadPool(batches);

        for (int i = 0; i < batches; i++) {
            // 计算当前批次要处理的用户ID范围
            int start = i * batchSize;
            int end = Math.min(start + batchSize, userIds.size());
            List<Long> batchIds = userIds.subList(start, end);

            // 创建一个 CompletableFuture 处理批次请求
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                // 调用UserService.getUserMap获取批次用户ID对应的昵称
                Map<Long, String> batchUserMap = UserService.getUserMap(batchIds, requestTimePerBatch);

                // 将批次用户ID对应的昵称添加到总的用户ID映射中
                resultMap.putAll(batchUserMap);
            }, executor);

            futures.add(future);
        }

        // 等待所有 CompletableFuture 完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

        // 设置超时时间为 200ms
        try {
            allOf.get(200, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            // 如果超时，取消未完成的任务
            allOf.cancel(true);
        }

        // 关闭线程池
        executor.shutdown();
        return resultMap;
    }

    // 模拟UserService类，实际应该根据实际情况调用真实的服务
    static class UserService {
        public static Map<Long, String> getUserMap(List<Long> userIds, int requestTime) {
            // 模拟耗时请求
            try {
                Thread.sleep(requestTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 模拟返回用户ID对应的昵称
            Map<Long, String> userMap = new HashMap<>();
            for (Long userId : userIds) {
                userMap.put(userId, "User" + userId);
            }
            return userMap;
        }
    }

    public static void main(String[] args) {
        Service service = new Service();
        List<Long> userIds = new ArrayList<>();
        for (long i = 1; i <= 1000; i++) {
            userIds.add(i);
        }

        long startTime = System.currentTimeMillis();
        Map<Long, String> result = service.get(userIds);
        long endTime = System.currentTimeMillis();
        System.out.println("耗时：" + (endTime - startTime) + "ms");
        System.out.println("结果数量：" + result.size());
        System.out.println("结果：" + result);
    }
}